package rs.etf.mips.crossroad.logic.lightcontrol;

import rs.etf.mips.crossroad.logic.Crossroad;
import rs.etf.mips.crossroad.logic.Light;
import rs.etf.mips.crossroad.logic.Line;
import rs.etf.mips.crossroad.logic.PedestrianSemaphore;
import rs.etf.mips.crossroad.logic.StreetDirection;
import rs.etf.mips.crossroad.logic.PedestrianSemaphore.State;

public class LightStateHorizontalLeftRight extends LightState {

	LightStateHorizontalLeftRight(Crossroad crossroad, long initCounter) {
		super(crossroad, initCounter);
	}


	@Override
	protected void updateCrossroadLights() {
		Light light = this.calculateLight();
		
		Line line = this.crossroad.getStreet(StreetDirection.East).getLine(3);
		this.setLineLight(line, light);
		line = this.crossroad.getStreet(StreetDirection.West).getLine(3);
		this.setLineLight(line, light);
		
		if (this.isInertiaRedPeriodPassed()) {
			light = Light.Green;
		}
		
		line = this.crossroad.getStreet(StreetDirection.East).getLine(5);
		this.setLineLight(line, light);
		line = this.crossroad.getStreet(StreetDirection.West).getLine(5);
		this.setLineLight(line, light);		
	}

	@Override
	protected LightState nextState() {
		return LightStateFactory.instance().
				getLightState(LightStateDescriptor.HorizontalRightForward);
	}


	@Override
	protected void updatePedestrianDisplay() {

		long pedTime = 0;
		PedestrianSemaphore.State state = State.Waiting;

		refreshArrivals(Direction.Vertical);
		refreshArrivals(Direction.Horizontal);

		LightStateFactory factory = LightStateFactory.instance();

		pedTime = redPeriod
				+ this.counter
				+ factory
						.getLightState(LightStateDescriptor.HorizontalRightForward).initCounter;
		if (Direction.Vertical.isArrived()) {
			pedTime -= factory
					.getLightState(LightStateDescriptor.HorizontalRightForward).maxTimeTaken;
		}

		PedestrianSemaphore semaphore = this.crossroad.getStreet(
				StreetDirection.South).getPedestrianSemaphore();
		semaphore.setState(state);
		semaphore.setTimeLeft(pedTime);

		semaphore = this.crossroad.getStreet(StreetDirection.North)
				.getPedestrianSemaphore();
		semaphore.setState(state);
		semaphore.setTimeLeft(pedTime);

		// update vertical
		pedTime = redPeriod
				+ this.counter + this.timeTaken
				+ factory
						.getLightState(LightStateDescriptor.VerticalRightForward).initCounter
				+factory
						.getLightState(LightStateDescriptor.HorizontalForward).initCounter
				+ factory.getLightState(LightStateDescriptor.VerticalLeftRight).initCounter
				+ factory
						.getLightState(LightStateDescriptor.HorizontalRightForward).initCounter;
		if (Direction.Horizontal.isArrived()) {
			pedTime -= factory.getLightState(LightStateDescriptor.VerticalLeftRight).maxTimeTaken
					+ factory
					.getLightState(LightStateDescriptor.VerticalRightForward).maxTimeTaken;
		}

		semaphore = this.crossroad.getStreet(StreetDirection.West)
				.getPedestrianSemaphore();
		semaphore.setState(state);
		semaphore.setTimeLeft(pedTime);

		semaphore = this.crossroad.getStreet(StreetDirection.East)
				.getPedestrianSemaphore();
		semaphore.setState(state);
		semaphore.setTimeLeft(pedTime);
	}

	@Override
	protected void initializeState() {
		this.timeTaken = 0;
		refreshArrivals(Direction.Vertical);
		if (Direction.Vertical.isArrived()) {
			this.counter = this.initCounter - this.maxTimeTaken;
			this.timeTaken = this.maxTimeTaken;
		}
		
	}


	@Override
	protected long timeGained() {
		return -timeTaken;
	}
}
